/*
 * Copyright (c) 2008-2023, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.huaweicloud;

import com.hazelcast.internal.json.Json;
import com.hazelcast.internal.json.JsonObject;
import com.hazelcast.spi.utils.RestClient;
import com.huaweicloud.sdk.core.internal.Iam;
import com.huaweicloud.sdk.core.internal.model.Credential;

import java.util.HashMap;
import java.util.Map;

/**
 * Responsible for connecting to the Ecs Instance Metadata API.
 */
public class HwMetadataApi {
    private static final String METADATA_URL = "http://169.254.169.254/openstack/latest/meta_data.json";
    private final String endpoint;
    private final Map<String, String> metadata;

    public HwMetadataApi() {
        this(METADATA_URL, new HashMap<>());
    }

    public HwMetadataApi(String endpoint, Map<String, String> metadata) {
        this.endpoint = endpoint;
        this.metadata = metadata;
    }

    // Server ID
    public String getInstanceId() {
        return this.getMetadataValue("uuid");
    }

    // availability_zone
    public String getAvailabilityZone() {
        return getMetadataValue("availability_zone");
    }

    // project id
    public String getProjectId() {
        return this.getMetadataValue("project_id");
    }

    // region
    public String getRegionId() {
        return this.getMetadataValue("region_id");
    }

    private String getMetadataValue(String property) {
        this.fillMetadata();
        return this.metadata.get(property);
    }

    private void fillMetadata() {
        if (this.metadata.isEmpty()) {
            String response = this.callGet(this.endpoint);

            JsonObject jsonObject = Json.parse(response).asObject();
            for (String property : jsonObject.names()) {
                if (jsonObject.get(property).isString()) {
                    metadata.put(property, jsonObject.get(property).asString());
                }
            }
        }
    }

    private String callGet(String urlString) {
        return RestClient.create(urlString).get().getBody();
    }

    // temporary ak、sk from metadata by IAM
    // with header 'X-Security-Token':securityToken
    public Map<String, String> accessToken() {
        HashMap<String, String> akAndSkMap = new HashMap<>();
        Credential credentialFromMetadata = Iam.getCredentialFromMetadata();
        akAndSkMap.put("access", credentialFromMetadata.getAccess());
        akAndSkMap.put("secret", credentialFromMetadata.getSecret());
        akAndSkMap.put("token", credentialFromMetadata.getSecurityToken());
        return akAndSkMap;
    }

}
